package pers.hl.library.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import pers.hl.library.auth.JwtUtils;
import pers.hl.library.auth.TimeoutMemoryCacheHelper;
import pers.hl.library.common.Response;
import pers.hl.library.common.base.LibBaseController;
import pers.hl.library.enums.FileType;
import pers.hl.library.po.FileEntity;
import pers.hl.library.po.User;
import pers.hl.library.service.FileService;
import pers.hl.library.service.UserService;
import pers.hl.library.utils.ExceptionHelper;
import pers.hl.library.utils.FileUtils;
import pers.hl.library.utils.MD5Utils;
import pers.hl.library.utils.QRFileSaveHelper;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("user")
public class UserController extends LibBaseController<User> {

    @Autowired
    UserService userService;
    @Autowired
    FileService fileService;

    private final TimeoutMemoryCacheHelper cacheService = TimeoutMemoryCacheHelper.getInstance();

    @Autowired
    public UserController(UserService userService) {
        init(userService);
    }

    @Override
    protected String getBussName() {
        return "用户";
    }

    /**
     * 登录
     * @param account 账号
     * @param password 密码
     * @return
     */
    @PostMapping("login")
    public Response login(@RequestParam("account") String account, @RequestParam("password") String password) {
        Map<String, Object> map = new HashMap<>();
        if (!userService.exist(account)) {
            return Response.fail_401("用户不存在");
        }
        User user = userService.getUser(account, password);
        if (user != null) {
            map.put("user", user);
            // 生成token写入缓存
            String token = JwtUtils.createToken(map);
            System.out.println("生成token:"+token);
            user.setToken(token);
            map.put("user", user);
            cacheService.add(String.valueOf(user.getUserId()), user, JwtUtils.TOKEN_EXPIRE_MILLIS);
            fillOtherPersonInfo(user);
            return Response.ok("登录成功", user);
        } else {
            return Response.fail_401("登录失败，密码错误");
        }
    }

    /**
     * 填充用户其他信息，如分享、关注、粉丝数量等
     * @param user
     */
    private void fillOtherPersonInfo(User user) {
        Integer sharingCount = userService.getSharingCount(user.getUserId());
        user.setSharingCount(sharingCount);
        Integer followCount = userService.getFollowCount(user.getUserId());
        user.setFollowCount(followCount);
        Integer fansCount = userService.getFansCount(user.getUserId());
        user.setFansCount(fansCount);
    }

    /**
     * 注册,密码采用MD5加密（或者是叫编码？）
     *
     * @return
     */
    @PostMapping("sign_up")
    public Response signUp(@RequestParam("account") String account, @RequestParam("password") String password) {
        String encodePwd = MD5Utils.string2MD5(password);
        User user = new User();
        user.setAccount(account);
        user.setPassword(encodePwd);
        user.setUserRole(User.ROLE_COMMON);
        if (userService.exist(account)) {
            return Response.fail_401("该账号已被注册");
        }
        if (userService.addData(user)) {
            createUserAvatar(user.getUserId());
            return Response.ok("用户注册成功");
        }
        return Response.fail_500("注册失败");
    }

    /**
     * 生成用户头像及二维码
     * @param userId 用户id
     */
    private void createUserAvatar(Integer userId) {
        try {
            QRFileSaveHelper.saveFile(FileType.value(FileType.USER_AVATAR), userId, fileService);
            QRFileSaveHelper.saveFile(FileType.value(FileType.USER_QR_CODE), userId, fileService);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @GetMapping("info/{userId}")
    public Response info(@PathVariable Integer userId) {
        return Response.ok(userService.getDataByPrimaryId(userId));
    }

    /**
     * 修改密码
     *
     * @param account     账号
     * @param password    原密码
     * @param newPassword 新密码
     */
    @PostMapping("modify_pwd")
    public Response modifyPwd(@RequestParam("account") String account, @RequestParam("password") String password, @RequestParam("newPassword") String newPassword) {
        if (StringUtils.isEmpty(password)) {
            return Response.fail_400("原密码不能为空");
        }
        if (StringUtils.isEmpty(newPassword)) {
            return Response.fail_400("新密码不能为空");
        }
        if (userService.getUser(account, password) == null) {
            return Response.fail_500("原密码校验失败");
        }
        User user = new User();
        User requestUser = getCurrentUser();
        if (null == requestUser) {
            return Response.fail_401("未获取到当前登录用户，请重新登录");
        }
        user.setUserId(requestUser.getUserId());
        user.setAccount(account);
        user.setPassword(newPassword);
        if (userService.modifyPwd(user)) {
            // todo 修改密码以后，让之前的token失效
            return Response.ok("修改成功");
        } else {
            return Response.fail_500("修改失败");
        }
    }

    @GetMapping("/list")
    public Response list() {
        User curUser = getCurrentUser();
        if (!curUser.isAdmin()) {
            return Response.fail_401("抱歉，您没有权限查看");
        }
        return Response.ok("获取所有用户成功", userService.getDataList(null, null));
    }

    /**
     * 获取用户头像，如有多条数据，以最新的为准
     *
     * @param request  请求
     * @param response 响应
     * @param userId   用户id
     */
    @GetMapping("avatar/{userId}")
    public void getAvatar(HttpServletRequest request, HttpServletResponse response, @PathVariable Integer userId) throws Exception {
        if (userId <= 0) {
            throw new IllegalArgumentException("用户id不能为空");
        }
        getQrImage(FileType.value(FileType.USER_AVATAR), userId, request, response);
    }

    private void getQrImage(int fileType, int bussId, HttpServletRequest request, HttpServletResponse response) {
        FileEntity fileEntity = fileService.getNewestByPrimaryId(fileType, bussId);
        if (null == fileEntity) {
            ExceptionHelper.throw404("未找到头像");
        }
        String realPath = fileEntity.getFileUrl();
        try {
            FileUtils.readFile(request, response, realPath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void afterGetDataByPrimaryId(User user) {
        fillOtherPersonInfo(user);
    }
}
